<html>

<table width=100%><tr>
    <td align=left> <a href="updates_api.html">&lt;- Dynamic Updates using the API</a></td>
    <td align=right><a href="updates_shmem.html">Dynamic Updates using Shared Memory -&gt;</a></td>
</tr></table>
<hr>

<h2>Dynamic Updates Using a Shared Object Callback</h2>

 <p>
 Often it is desirable to use a utility such as <b>osgviewer</b>, to view a 
 model and not write a complete application from scratch, just to be able
 to plug in certain functionality.  osgEphemeris is a good example of a
 component you might want to add to a scene without having to write a 
 special viewer just to see it.  

 <p>
 <b>osgEphemeris</b> allows you to write an EphemerisUpdateCallback and 
 compile it as a shared object, which can be loaded by a directive in a .osg
 file.  Here we will see the steps required to make this work.  We will use
 an example provided in src/CallbackExample in the distribution.  Here
 we create a simple callback named "TimePassesCallback", which begins by
 ticking off 60 seconds for every frame, beginning with 0 of the UNIX epoch
 (midnight, Jan 1, 1970).  

 Here is the .cpp file:
  <p>
  <table width=100%><tr><td bgcolor=#DDDDDD>
  <blockquote>
    <pre>

    #include &lt;time.h&gt;
    #include &lt;osgEphemeris/EphemerisUpdateCallback.h&gt;
    #include &lt;osgEphemeris/EphemerisData.h&gt;
    
    class TimePassesCallback : public osgEphemeris::EphemerisUpdateCallback
    {
        public:
            TimePassesCallback(): EphemerisUpdateCallback( "TimePassesCallback" ),
                 _seconds(0)
            {}
    
            void operator()( osgEphemeris::EphemerisData *data )
            {
                 _seconds += 60;
                 struct tm *_tm = localtime(&_seconds);
    
                 data-&gt;dateTime.setYear( _tm-&gt;tm_year + 1900 );    // DateTime uses _actual_ year (not since 1900)
                 data-&gt;dateTime.setMonth( _tm-&gt;tm_mon + 1 );       // DateTime numbers months from 1 to 12, not 0 to 11
                 data-&gt;dateTime.setDayOfMonth( _tm-&gt;tm_mday + 1 ); // DateTime numbers days from 1 to 31, not 0 to 30
                 data-&gt;dateTime.setHour( _tm-&gt;tm_hour );
                 data-&gt;dateTime.setMinute( _tm-&gt;tm_min );
                 data-&gt;dateTime.setSecond( _tm-&gt;tm_sec );
            }
    
        private:
            time_t _seconds;
    };
    
    osgEphemeris::EphemerisUpdateCallbackProxy&lt;TimePassesCallback&gt; _timePassesCallbackProxy;
</pre>
    </blockquote>
    </td></tr></table>

    <p>
    This is quite similar to the previous section callback, other than the fact 
    that we are not using the current time, but setting some artificial passage
    of time.  
    
    <p>
    There is one line at the end of the file, which defines a static instance
    of a <b>EphemerisUpdateCallbackProxy</b> class.  The role of this class is 
    to register the callback with an internal registry of callbacks, so it is 
    available for later use.

    <p>
    Also, important to note, is the string that we pass the 
    <b>EphemerisUpdateCallback</b> super class.  This is the <i>name</i> of the
    callback and something we will be using as a directive parameter in 
    our .osg file format later.
    

    <p>
    This file can then be compiled into a shared object named "TimePasses" (no 
    extension is really necessary).
  <p>
  <table width=100%><tr><td bgcolor=#DDDDDD>
  <blockquote>
  <pre>

    g++  -O2   -shared -fPIC timePasses.cpp     -o TimePasses
  </pre>
  </blockquote>
  </td></tr></table>

  <p>
  Place this file <b>TimePasses</b> into a directory within your OSG_FILE_PATH
  definition or in a standard place where osgDB will find it.

  <p>
  Next, add the necessary directive to the <b>ephemeris.osg</b> file:

  <p>
  <table width=100%><tr><td bgcolor=#DDDDDD>
  <blockquote>
  <pre>

    osgEphemerisModel::EphemerisModel {
        UniqueID EphemerisModel_0

        Latitude 38.4765
        Longitude -122.493
        DateTime 20060224162800
        SkyDomeRadius 200000
        AutoDateTime False
        MoveWithEyePoint True

        <b>UpdateCallback TimePasses::TimePassesCallback</b>
    }

  </pre>
  </blockquote>
  </td></tr></table>

  <p>
  By adding <b>UpdateCallback TimePasses::TimePassesCallback</b>, we've directed
  the NodeKit to load a callback named <b>TimePassesCallback</b> from a shared
  object named <b>TimePasses</b>.  You can now run the following and watch
  time pass over your terrain database:

  <p>
  <table width=100%><tr><td bgcolor=#DDDDDD>
  <blockquote>
  <pre>

    osgviewer --clear-color 0,0,0,1 myTerrain.osg ephemeris.osg
  </pre>
  </blockquote>
  </td></tr></table>

<hr>
<table width=100%><tr>
    <td align=left> <a href="updates_api.html">&lt;- Dynamic Updates using the API</a></td>
    <td align=right><a href="updates_shmem.html">Dynamic Updates using Shared Memory -&gt;</a></td>
</tr></table>
</html>
